#include "Tcp_Sock.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/**
 * @brief TCP服务端初始化
 * 
 * @param ip 
 * @param port 
 * @return int 
 */
int Service_Init(char ip[], int port)
{
    int server_fd;
    struct sockaddr_in addr;
    int opt = 1;

    /* 创建服务器套接字 */
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("套接字创建失败");
        return -1;
    }

    /* 初始化地址结构 */
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);

    /* 设置套接字选项 */
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))
    {
        perror("套接字选项设置失败");
        close(server_fd);
        return -1;
    }

    /* 绑定端口 */
    if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("绑定失败");
        close(server_fd);
        return -1;
    }

    #if 0
    /* 设置连接超时 */
    struct timeval timeout = {5, 0}; // 5秒超时
    if (setsockopt(server_fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0)
    {
        perror("设置超时失败");
        close(server_fd);
        return -1;
    }
    #endif

    /* 开始监听 */
    if (listen(server_fd, 10) < 0)
    {
        perror("监听失败");
        close(server_fd);
        return -1;
    }
    printf("服务器运行中 (端口: %d)...\n", port);
    return server_fd;
}

/**
 * @brief TCP服务端关闭
 * 
 * @param fd 
 */
void Service_Close(int fd)
{
    close(fd);
}

/**
 * @brief TCP客户端初始化
 * 
 * @param ip 
 * @param port 
 * @return int 
 */
int Client_Init(char ip[], int port)
{
    int sockfd;
    struct sockaddr_in serv_addr;

    /* 创建套接字 */
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("套接字创建失败");
        return -1;
    }

    /* 初始化服务器地址结构 */
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);

    /* 转换IP地址 */
    if (inet_pton(AF_INET, ip, &serv_addr.sin_addr) <= 0)
    {
        perror("地址转换错误");
        close(sockfd);
        return -1;
    }

    #if 0
    /* 设置连接超时 */
    struct timeval timeout = {5, 0}; // 5秒超时
    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0)
    {
        perror("设置超时失败");
        close(sockfd);
        return -1;
    }
    #endif

    /* 连接服务器 */
    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        perror("连接失败");
        close(sockfd);
        return -1;
    }

    printf("连接服务器成功!\n");
    return sockfd;
}

/**
 * @brief TCP客户端关闭
 * 
 * @param fd 
 */
void Client_Close(int fd)
{
    close(fd);
}